package com.gitee.wsl.ext.db

import androidx.room.InvalidationTracker
import androidx.room.RoomDatabase
import androidx.room.TransactionScope
import androidx.room.Transactor
import androidx.room.TypeConverter
import androidx.room.useReaderConnection
import androidx.room.useWriterConnection
import androidx.sqlite.SQLiteStatement
import kotlinx.coroutines.flow.Flow
import kotlinx.datetime.LocalDateTime

class LocalDateTimeConverter {
    @TypeConverter
    fun fromTimestamp(value: String?): LocalDateTime? {
        return value?.let { LocalDateTime.parse(it) }
    }

    @TypeConverter
    fun dateToTimestamp(date: LocalDateTime?): String? {
        return date?.toString()
    }
}


// FIXME: Added a hack to resolve below issue:
// Class 'AppDatabase_Impl' is not abstract and does not implement abstract base class member 'clearAllTables'.
interface DB {
    fun clearAllTables() {}
}

suspend fun <T> RoomDatabase.withTransaction(block: suspend TransactionScope<T>.() -> T): T =
    useWriterConnection { transactor ->
        transactor.withTransaction(Transactor.SQLiteTransactionType.IMMEDIATE) {
            block()
        }
    }

suspend fun <T> RoomDatabase.rawQuery(query: String, block: (SQLiteStatement) -> T): T =
    useReaderConnection { transactor -> transactor.usePrepared(query) { block(it) } }

fun InvalidationTracker.observeAsFlow(tables: Array<String>): Flow<Set<String>> = createFlow(tables = tables)
//    callbackFlow {
//        val observer = FlowInvalidationObserver(tables, this)
//        subscribe(observer)
//        awaitClose {
//            runBlocking {
//                unsubscribe(observer)
//            }
//        }
//    }.onStart { emit(emptySet()) }
//
//private class FlowInvalidationObserver(
//    tables: Array<String>,
//    private val producerScope: ProducerScope<Set<String>>,
//) : InvalidationTracker.Observer(tables) {
//    override fun onInvalidated(tables: Set<String>) {
//        producerScope.trySendBlocking(tables)
//    }
//}

//fun SupportSQLiteDatabase.delete(
//    table: String,
//    whereClause: String?,
//    whereArgs: Array<out Any?>?
//): Int {
//    val query = ("DELETE FROM " + table
//            + if (whereClause.isNullOrEmpty()) "" else " WHERE $whereClause")
//    val statement = compileStatement(query)
//
//    return try {
//        SimpleSQLiteQuery.bind(statement, whereArgs)
//        statement.executeUpdateDelete()
//    } finally {
//        try {
//            statement.close()
//        } catch (e: Exception) {
//            throw RuntimeException("Exception attempting to close statement", e)
//        }
//    }
//}


//expect inline fun <reified T: RoomDatabase> roomDatabaseBuilder(name: String, isMultiInstance:Boolean = false): RoomDatabase.Builder<T>